package common		//data type define & convert

import (
	"fmt"
	"reflect"
	"encoding/json"
	"github.com/tidwall/gjson"
)

/*
 显示反射类型的 结构体 内部 各个字段的名称，字段数量
 入口参数 ->>  
  		接口类型
 */
func PrintIfFields(If interface{}) {
	var t reflect.Type
	t = reflect.TypeOf(If)

	fmt.Println("NumField           :", t.NumField()) // 字段数量
	if t.NumField() > 0 {
		var i, j int
		// 遍历结构体字段
		for i = 0; i < t.NumField()-1; i++ {
			field := t.Field(i) // 获取结构体字段
			fmt.Printf("    ├ %v\n", field.Name)
			// 遍历嵌套结构体字段
			if field.Type.Kind() == reflect.Struct && field.Type.NumField() > 0 {
				for j = 0; j < field.Type.NumField()-1; j++ {
					subfield := t.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
					fmt.Printf("    │    ├ %v\n", subfield.Name)
				}
				subfield := t.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
				fmt.Printf("    │    └ %%v\n", subfield.Name)
			}
		}
		field := t.Field(i) // 获取结构体字段
		fmt.Printf("    └ %v\n", field.Name)
		// 通过名称查找字段
		if field, ok := t.FieldByName("ptr"); ok {
			fmt.Println("FieldByName(ptr)   :", field.Name)
		}
		// 通过函数查找字段
		if field, ok := t.FieldByNameFunc(func(s string) bool { return len(s) > 3 }); ok {
			fmt.Println("FieldByNameFunc    :", field.Name)
		}
	}
}

func PrintIfType(i interface{}) {
	var t reflect.Type
	t = reflect.TypeOf(i)
	fmt.Printf("Structure type name with package name: <%v>\n", t)
	fmt.Printf("Structure type name: <%v>\n", t.Name())
	fmt.Printf("Structure kind: <%v>\n", t.Kind())
	
}

func PrintIfValue(i interface{}) {
	var v reflect.Value
	v = reflect.ValueOf(i) 
	fmt.Printf("Structure values: %v\n", v)
}

/*
 通过 key ，获取对应的value
 入口参数 ->>
 		interface {}
 */
func IfVal_string(i interface {}, k string) string {
	Struct := reflect.ValueOf(i)
	v := Struct.FieldByName(k)
	val := fmt.Sprintf("%s", v)
	return val
}

func IfVal_integer(i interface {}, k string) int {
	Struct := reflect.ValueOf(i)
	v := Struct.FieldByName(k).Int()  //int64
	val := (int)(v)  //int64 转 int
	return val
}

func IfVal_float32(i interface {}, k string) float32 {
	Struct := reflect.ValueOf(i)
	v := Struct.FieldByName(k).Float()
	val := (float32)(v) 
	return val
}

func IfVal_float64(i interface {}, k string) float64 {
	Struct := reflect.ValueOf(i)
	v := Struct.FieldByName(k).Float()
	val := (float64)(v) 
	return val
}

func IfVal_ObjectID(i interface{}, k string) string {
	Struct := reflect.ValueOf(i)
	v := Struct.FieldByName(k)
	id := fmt.Sprintf("%v", v)
	return id
}

func If2KV(i interface{}) string {
	jsonBYTEs, _ := json.Marshal(i)	//返回json字节流
	//fmt.Println(jsonBYTEs)
	String := string(jsonBYTEs) //byte字节流转换为string字符串
	//fmt.Println(String)
	return String
}

func If2KVbytes(i interface{}) []byte {
	jsonBYTEs, _ := json.Marshal(i)	//返回json字节流
	return jsonBYTEs
}

/*
 结构体的interface{} 类型转换为Golang 字典/散列表 map类型
 结构体中所有值都保存为string类型
 */
func If2Map(i interface{}) map[string]string {
	j := fmt.Sprintf("%s", If2KV(i))

	key := gjson.Get(j, "#.Key")
	value := gjson.Get(j, "#.Value")
	/*
	for _, k := range key.Array() {	fmt.Printf("%s\n", k) }
	for _, v := range value.Array() { fmt.Printf("%s\n", v.String()) } */

	// sz_k := len(key.Array()); sz_v := len(value.Array())
	// fmt.Printf("key len: %d\tvalue len: %d\n", sz_k, sz_v)
	dic := make(map[string]string)
	var x int
	for x = 0; x < len(key.Array()); x++ {
		k := fmt.Sprintf("%s", key.Array()[x])
		v := fmt.Sprintf("%s", value.Array()[x])
		dic[k] = v
	} 
	//fmt.Println(dic)
	return dic
}
